﻿#if !WindowsCE
using System;
using System.Collections.Specialized;
using System.Xml;

namespace FireEagleNet
{
    /// <summary>
    /// Configuration settings for the FireEagle.Net API Library.
    /// </summary>
    /// <remarks>
    /// <p>First, register the configuration section in the configSections section:</p>
    /// <p><code>&lt;configSections&gt;
    /// &lt;section name="FireEagleNet" type="FireEagleNet.FireEagleConfigurationManager,FireEagleNet"/&gt;
    /// &lt;/configSections&gt;</code>
    /// </p>
    /// <p>
    /// Next, include the following config section:
    /// </p>
    /// <p><code>
    /// 	&lt;FireEagleNet 
    /// apiKey="1234567890abc"	// optional
    /// secret="2134123"		// optional
    /// token="234234"			// optional
    /// cacheSize="1234"		// optional, in bytes (defaults to 50 * 1024 * 1024 = 50MB)
    /// cacheTimeout="[d.]HH:mm:ss"	// optional, defaults to 1 day (1.00:00:00) - day component is optional
    /// // e.g. 10 minutes = 00:10:00 or 1 hour = 01:00:00 or 2 days, 12 hours = 2.12:00:00
    /// &gt;
    /// &lt;proxy		// proxy element is optional, but if included the attributes below are mandatory as mentioned
    /// ipaddress="127.0.0.1"	// mandatory
    /// port="8000"				// mandatory
    /// username="username"		// optional, but must have password if included
    /// password="password"		// optional, see username
    /// domain="domain"			// optional, used for Microsoft authenticated proxy servers
    /// /&gt;
    /// &lt;/FireEagleNet&gt;
    /// </code></p>
    /// </remarks>
    internal class FireEagleConfigurationSettings
    {
        #region Private Variables
        private string m_api;
        private string m_secret;
        private string m_token;
		private string m_tokensecret;
		private string m_general;
		private string m_generalsecret;
        private string m_pAddress;
        private int m_pPort;
        private bool m_pIsDefined;
        private string m_pUser;
        private string m_pPass;
        private string m_pDomain;
        #endregion

        #region FireEagleConfigurationSettings Constructor
        /// <summary>
        /// Loads FireEagleConfigurationSettings with the settings in the config file.
        /// </summary>
        /// <param name="configNode">XmlNode containing the configuration settings.</param>
        public FireEagleConfigurationSettings(XmlNode configNode)
        {
            if (configNode == null) throw new ArgumentNullException("configNode");

            foreach (XmlAttribute attribute in configNode.Attributes)
            {
                switch (attribute.Name)
                {
                    case "apiKey":
                        m_api = attribute.Value;
                        break;
                    case "secret":
                        m_secret = attribute.Value;
                        break;
					case "token":
						m_token = attribute.Value;
						break;
					case "tokensecret":
						m_tokensecret = attribute.Value;
						break;
					case "general":
						m_general = attribute.Value;
						break;
					case "generalecret":
						m_generalsecret = attribute.Value;
						break;
					default:
                        throw new System.Configuration.ConfigurationErrorsException(String.Format("Unknown attribute '{0}' in FireEagleNet node", attribute.Name), configNode);
                }
            }

            foreach (XmlNode node in configNode.ChildNodes)
            {
                switch (node.Name)
                {
                    case "proxy":
                        ProcessProxyNode(node, configNode);
                        break;
                    default:
                        throw new System.Configuration.ConfigurationErrorsException(String.Format("Unknown node '{0}' in FireEagleNet node", node.Name), configNode);
                }
            }
        }
        #endregion

        #region ProcessProxyNode - Constructor Helper Method
        private void ProcessProxyNode(XmlNode proxy, XmlNode configNode)
        {
            if (proxy.ChildNodes.Count > 0)
                throw new System.Configuration.ConfigurationErrorsException("proxy element does not support child elements");

            m_pIsDefined = true;
            foreach (XmlAttribute attribute in proxy.Attributes)
            {

                switch (attribute.Name)
                {
                    case "ipaddress":
                        m_pAddress = attribute.Value;
                        break;
                    case "port":
                        try
                        {
                            m_pPort = int.Parse(attribute.Value);
                        }
                        catch (FormatException ex)
                        {
                            throw new System.Configuration.ConfigurationErrorsException("proxy port should be integer value", ex, configNode);
                        }
                        break;
                    case "username":
                        m_pUser = attribute.Value;
                        break;
                    case "password":
                        m_pPass = attribute.Value;
                        break;
                    case "domain":
                        m_pDomain = attribute.Value;
                        break;
                    default:
                        throw new System.Configuration.ConfigurationErrorsException(String.Format("Unknown attribute '{0}' in FireEagleNet/proxy node", attribute.Name), configNode);
                }
            }

            if (m_pAddress == null)
                throw new System.Configuration.ConfigurationErrorsException("proxy ipaddress is mandatory if you specify the proxy element");
            if (m_pPort == 0)
                throw new System.Configuration.ConfigurationErrorsException("proxy port is mandatory if you specify the proxy element");
            if (m_pUser != null && m_pPass == null)
                throw new System.Configuration.ConfigurationErrorsException("proxy password must be specified if proxy username is specified");
            if (m_pUser == null && m_pPass != null)
                throw new System.Configuration.ConfigurationErrorsException("proxy username must be specified if proxy password is specified");
            if (m_pDomain != null && m_pUser == null)
                throw new System.Configuration.ConfigurationErrorsException("proxy username/password must be specified if proxy domain is specified");
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// API key. Null if not present. Optional.
        /// </summary>
        public string ApiKey
        {
            get { return m_api; }
        }

        /// <summary>
        /// Shared Secret. Null if not present. Optional.
        /// </summary>
        public string SharedSecret
        {
            get { return m_secret; }
        }

		/// <summary>
		/// API token. Null if not present. Optional.
		/// </summary>
		public string ApiToken
		{
			get { return m_token; }
		}

		/// <summary>
		/// API secret token. Null if not present. Optional.
		/// </summary>
		public string ApiTokenSecret
		{
			get { return m_tokensecret; }
		}

		/// <summary>
		/// API token. Null if not present. Optional.
		/// </summary>
		public string ApiGeneral
		{
			get { return m_general; }
		}

		/// <summary>
		/// API secret token. Null if not present. Optional.
		/// </summary>
		public string ApiGeneralSecret
		{
			get { return m_generalsecret; }
		}

		/// <summary>
        /// If the proxy is defined in the configuration section.
        /// </summary>
        public bool IsProxyDefined
        {
            get { return m_pIsDefined; }
        }

        /// <summary>
        /// If <see cref="IsProxyDefined"/> is true then this is mandatory.
        /// </summary>
        public string ProxyIPAddress
        {
            get { return m_pAddress; }
        }

        /// <summary>
        /// If <see cref="IsProxyDefined"/> is true then this is mandatory.
        /// </summary>
        public int ProxyPort
        {
            get { return m_pPort; }
        }

        /// <summary>
        /// The username for the proxy. Optional.
        /// </summary>
        public string ProxyUsername
        {
            get { return m_pUser; }
        }

        /// <summary>
        /// The password for the proxy. Optional.
        /// </summary>
        public string ProxyPassword
        {
            get { return m_pPass; }
        }

        /// <summary>
        /// The domain for the proxy. Optional.
        /// </summary>
        public string ProxyDomain
        {
            get { return m_pDomain; }
        }
        #endregion

    }
}
#endif